package com.g2room.driving.generate.kcjq;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.g2room.driving.model.po.Article;
import com.g2room.driving.model.po.Category;
import com.g2room.driving.util.Constants;
import com.g2room.driving.util.DbUtil;
import com.g2room.driving.util.HtmlUtil;
import com.g2room.driving.util.ImageUtil;

import freemarker.template.Configuration;
import freemarker.template.Template;

public class ReleaseArticle {

	private static String basePath = Constants.basePath+ "kaichejiqiao/";
	private static String baseHtmlPath = Constants.baseHtmlPath + "kaichejiqiao/";
//	private static String localImgDir = Constants.localImgDir + "driving/targetImg/";
	public static String publishHtmlPath = null;
	static String name = "kcjq";
	
	public static void createHtml() {
		 @SuppressWarnings("deprecation")
		 Configuration cfg = new Configuration();
		 try {
			 int updateId = 1;
			 String publishTime = DbUtil.getPublishTimeStr(updateId);
			 cfg.setDirectoryForTemplateLoading(new File(basePath));
			 System.out.println(name + "生成主页！");
			 createIndex(cfg);
			 System.out.println(name + "生成最新最热页！");
			 createLatest(cfg);
			 System.out.println(name + "生成列表页！");
			 createList(cfg, publishTime);
			 System.out.println(name + "生成详情页！");
			 createDetail(cfg, publishTime);
			 DbUtil.updateTime(updateId);
				// 关闭连接
				DbUtil.closeConn();
		} catch (IOException e) {
			System.out.println(name + "发生异常：" + e.getMessage());
			e.printStackTrace();
		}  
	}
	public static void createLatest(Configuration cfg) {
		try {
			Map<String, List<Article>> articleMap = new HashMap<String, List<Article>>();
			articleMap.put("latestArticles", getArticles("latest"));
			articleMap.put("hotArticles", getArticles("hotest"));
			StringWriter out = null;
			try {
				Template tmpl = cfg.getTemplate("latest.ftl");
				out = new StringWriter();
				tmpl.process(articleMap, out);
				// 生成文件
				createFile(out.toString(), "latest.html");
			} catch (Exception e) {
				System.out.println(name + "发生异常：" + e.getMessage());
				e.printStackTrace();
			} finally {
				try {
					if (null != out)
						out.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	public static void createDetail(Configuration cfg, String publishTime) {
		try {
			Map<String, List<Article>> articlesMap = new HashMap<String, List<Article>>();
			List<Article> articles = getDetails(publishTime);
			Template tmpl = cfg.getTemplate("detail.ftl");
			StringWriter out = null;
			Map<String, Object> articleMap = new HashMap<String, Object>();
			for(Article arti : articles) {
				try {
					String code = (null == arti.getTypeCode() || arti.getTypeCode().length()==0) ? arti.getCategoryCode() : arti.getTypeCode();
					List<Article> articleList = articlesMap.get(code);
					if(null == articleList || articleList.size() == 0) {
						articleList = new ArrayList<Article>();
						if(0 != arti.getCategoryId()) {
							articleList = getArticlesByCategoryId(arti.getCategoryId(), 10, publishTime);
						} else {
							articleList = getArticlesByTypeId(arti.getTypeId(), 10, publishTime);
						}
						articlesMap.put(code, articleList);
					}
					articleMap.put("article", arti);
					articleMap.put("recomms", articleList);
					out = new StringWriter();
					tmpl.process(articleMap, out);
					String catCode = arti.getCategoryCode();
					// 生成文件
					createFile(out.toString(), catCode + "/d"+ arti.getTypeCode() + arti.getId() +".html");
				} catch (Exception e) {
					e.printStackTrace();
				} finally {
					try {
						if (null != out)
							out.close();
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public static void createList(Configuration cfg, String publishTime) {
		try {
			List<Category> categories = getTypes();
			int pageSize = 30;
			// 处理安全驾驶和驾驶技巧类别
			for(Category category : categories) {
				Map<String, Object> articleMap = new HashMap<String, Object>();
				int count = 0 != category.getParentId() ? getArticlesCountByTypeId(category.getId(), publishTime) : getArticlesCountByCategoryId(category.getId(), publishTime);
				List<Article> articleList = null;
				if(count == 0) {
					continue;
				} else {
					if(0 != category.getParentId()) {
						articleList = getArticlesByTypeId(category.getId(), 100000, null);
					} else {
						articleList = getArticlesByCategoryId(category.getId(), 100000, null);
					}
				}
				for(int start = 0; (start) * pageSize < articleList.size(); start++) {
					articleMap.put("articles", articleList.subList(start * pageSize, ((start + 1) * pageSize >= articleList.size() ? articleList.size() : (start + 1) * pageSize)));
					articleMap.put("categoryName", category.getName());
					articleMap.put("categoryCode", category.getCode());
					articleMap.put("count", articleList.size());
					articleMap.put("pageSize", pageSize);
					articleMap.put("pageNo", start);
					
					Template tmpl = cfg.getTemplate("list.ftl");
					StringWriter out = null;
					try {
						out = new StringWriter();
						tmpl.process(articleMap, out);
						String typeCode = articleList.get(0).getTypeCode();
						String catCode = articleList.get(0).getCategoryCode();
						if(start==0 && category.getParentId().equals(0)) {
							createFile(out.toString(), category.getCode() + "/index.html");
						}
						createFile(out.toString(), catCode + "/list_"+ (0 == category.getParentId() ? catCode : typeCode) + "_" + (start+1) +".html");
					} catch (Exception e) {
						e.printStackTrace();
					} finally {
						try {
							if (null != out)
								out.close();
						} catch (Exception e) {
							e.printStackTrace();
						}
					}
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	public static void createIndex(Configuration cfg) {
		try {
			List<Article> articles = getTop5Articles();
			System.out.println(name + "获取文章列表：" + articles.size());
			Map<String, List<Article>> articleMap = new HashMap<String, List<Article>>();

			// 处理安全驾驶和驾驶技巧类别
			String typeCode = "";
			for(Article arti : articles) {
				typeCode = arti.getTypeCode();
				// safe单独处理
				if((null == typeCode || typeCode.length() == 0)  && arti.getCategoryCode().equals("safe")) {
					typeCode = arti.getCategoryCode();
					arti.setTypeCode(typeCode);
				}
				List<Article> articleList = articleMap.get(typeCode + "s");
				if(null == articleList) {
					articleList = new ArrayList<Article>();
				} else if(articleList.size() == 5) {
					continue;
				}

				articleList.add(arti);
				articleMap.put(typeCode + "s", articleList);
			}
			articleMap.put("slides", getSlides());
			articleMap.put("stickSummary", getStickSummary());
			articleMap.put("sticks", getSticks());
			articleMap.put("autocarSummary", getArticlesSummary(3));
			articleMap.put("womens", getArticlesByCategoryId(4, 10, null));
			articleMap.put("autocars", getArticlesByCategoryId(3, 10, null));
			articleMap.put("laws", getArticlesByCategoryId(5, 10, null));
			articleMap.put("beginners", getArticlesByCategoryId(2, 20, null));
			articleMap.put("maintains", getArticlesByCategoryId(16, 10, null));
			articleMap.put("knowledges", getArticlesByCategoryId(17, 5, null));
			Template tmpl = null;
			StringWriter out = null;
			try {
				System.out.println(name + "加载模板文件。");
				tmpl = cfg.getTemplate("index.ftl");
				out = new StringWriter();
				tmpl.process(articleMap, out);
				System.out.println(name + "本次生成文件路径："+HtmlUtil.getPath(baseHtmlPath));
				// 生成Mapper文件
				createFile(out.toString(), "index.html");
			} catch (Exception e) {
				System.out.println(name + "生成主页页面异常：" + e.getMessage());
				e.printStackTrace();
			} finally {
				try {
					if (null != out)
						out.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		} catch (Exception e) {
			System.out.println(name + "生成主页异常：" + e.getMessage());
			e.printStackTrace();
		}
	}
	
	public static void createFile(String content, String fileName) throws Exception {
		String filePath = baseHtmlPath + fileName;
        //得到写文件路径
        File file = new File(filePath.substring(0, filePath.lastIndexOf("/")));
        //如果目录不存在，则创建目录
        if(!file.exists())  file.mkdirs();
        //写文件
        OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(new File(filePath)),"utf-8");
//        publishHtmlPath = HtmlUtil.getPath(baseHtmlPath);
//        String tempFilePath =  publishHtmlPath + fileName;
//        //得到写文件路径
//        File file1 = new File(tempFilePath.substring(0, tempFilePath.lastIndexOf("/")));
//        //如果目录不存在，则创建目录
//        if(!file1.exists())  file1.mkdirs();
//        //写如待上传的目录文件
//        OutputStreamWriter out1 = new OutputStreamWriter(new FileOutputStream(new File(tempFilePath)),"utf-8");
//        out1.write(content);
//        out1.flush();
//        out1.close();
        
        out.write(content);
        out.flush();
        out.close();
    }

	public static List<Article> getTop5Articles() {
		List<Article> articles = new ArrayList<Article>();
		try {
			Connection connection = DbUtil.getConn();
			Statement statement = connection.createStatement();
//			String sql = "SELECT a.id,a.title,a.publish_time,a.category_id,a.category_code,a.type_id,a.type_code FROM d_article a where state=1 and (category_id=1 or category_id=5) and 5>=(SELECT COUNT(*) FROM d_article b WHERE a.category_id=b.category_id and (a.type_id=b.type_id or type_id is null) AND a.id<=b.id)";
			String sql = "SELECT a.id,a.title,a.publish_time,a.category_id,a.category_code,a.type_id,a.type_code FROM d_article a where state=1 and (category_id=1 or category_id=5) and 5>=(SELECT COUNT(*) FROM d_article b WHERE a.category_id=b.category_id and a.type_id=b.type_id AND a.id<=b.id)";
			ResultSet rs = statement.executeQuery(sql);
			while (rs.next()) {
				Article article = new Article();
				article.setId(rs.getLong("id"));
				article.setTitle(rs.getString("title"));
				article.setPublishTime(rs.getDate("publish_time"));
				article.setCategoryId(rs.getLong("category_id"));
				article.setCategoryCode(rs.getString("category_code"));
				article.setTypeId(rs.getLong("type_id"));
				article.setTypeCode(rs.getString("type_code"));
				articles.add(article);
			}
			rs.close();
			statement.close();
//			connection.close();
		} catch (Exception e) {
			e.printStackTrace();
			// 关闭连接
			DbUtil.closeConn();
		}
		return articles;
	}
	
	public static List<Article> getArticlesByCategoryId(long categoryId, int limit, String publishTime) {
		return getArticlesByCategoryId("category_id", categoryId, limit, publishTime);
	}
	
	public static List<Article> getArticlesByTypeId(long typeId, int limit, String publishTime) {
		return getArticlesByCategoryId("type_id", typeId, limit, publishTime);
	}
	public static List<Article> getArticlesByCategoryId(String field, long categoryId, int limit, String publishTime) {
		List<Article> articles = new ArrayList<Article>();
		try {
			Connection connection = DbUtil.getConn();
			Statement statement = connection.createStatement();
			String sql = "SELECT a.id,a.title,a.publish_time,a.category_id,a.category_code,a.type_id,a.type_code FROM d_article a "
					+ "where " + (isEmpty(publishTime) ? "" : "create_time>'" + publishTime + "' and ") 
					+ " state=1 and "+field+"=" + categoryId + " order by a.publish_time desc  limit " + limit;
			ResultSet rs = statement.executeQuery(sql);
			while (rs.next()) {
				Article article = new Article();
				article.setId(rs.getLong("id"));
				article.setTitle(rs.getString("title"));
				article.setPublishTime(rs.getDate("publish_time"));
				article.setCategoryId(rs.getLong("category_id"));
				article.setCategoryCode(rs.getString("category_code"));
				article.setTypeId(rs.getLong("type_id"));
				String typeCode = rs.getString("type_code");
				article.setTypeCode(isEmpty(typeCode) ? article.getCategoryCode() : typeCode);
				articles.add(article);
			}
			rs.close();
			statement.close();
//			connection.close();
		} catch (Exception e) {
			System.out.println(name + "获取数据发生异常：" + e.getMessage());
			e.printStackTrace();
			// 关闭连接
			DbUtil.closeConn();
		}
		return articles;
	}
	

	public static int getArticlesCountByCategoryId(long categoryId, String publishTime) {
		return getArticlesCountByCategoryId("category_id", categoryId, publishTime);
	}
	
	public static int getArticlesCountByTypeId(long typeId, String publishTime) {
		return getArticlesCountByCategoryId("type_id", typeId, publishTime);
	}
	public static int getArticlesCountByCategoryId(String field, long categoryId, String publishTime) {
		int count = 0;
		try {
			Connection connection = DbUtil.getConn();
			Statement statement = connection.createStatement();
			String sql = "SELECT count(*) as count FROM d_article a "
					+ "where " + (isEmpty(publishTime) ? "" : "create_time>'" + publishTime + "' and ") 
					+ " state=1 and "+field+"=" + categoryId;
			ResultSet rs = statement.executeQuery(sql);
			while (rs.next()) {
				count = rs.getInt("count");
			}
			rs.close();
			statement.close();
//			connection.close();
		} catch (Exception e) {
			System.out.println(name + "获取统计数据发生异常：" + e.getMessage());
			e.printStackTrace();
			// 关闭连接
			DbUtil.closeConn();
		}
		return count;
	}
	
	public static List<Article> getArticlesSummary(int categoryId) {
		List<Article> articles = new ArrayList<Article>();
		try {
			Connection connection = DbUtil.getConn();
			Statement statement = connection.createStatement();
			String sql = "SELECT a.id,a.title,a.publish_time,a.category_id,a.content,a.category_code,a.type_id,a.type_code FROM d_article a where state=1 and category_id=" 
					+ categoryId + " order by a.create_time desc  limit 1";
			ResultSet rs = statement.executeQuery(sql);
			while (rs.next()) {
				Article article = new Article();
				article.setId(rs.getLong("id"));
				article.setTitle(rs.getString("title"));
				article.setPublishTime(rs.getDate("publish_time"));
				article.setCategoryId(rs.getLong("category_id"));
				article.setCategoryCode(rs.getString("category_code"));
				article.setTypeId(rs.getLong("type_id"));
				article.setTypeCode(rs.getString("type_code"));
				article.setContent(HtmlUtil.delHTMLTag(rs.getString("content")).substring(0, 200));
				articles.add(article);
			}
			rs.close();
			statement.close();
//			connection.close();
		} catch (Exception e) {
			System.out.println(name + "获取文章摘要数据发生异常：" + e.getMessage());
			e.printStackTrace();
			// 关闭连接
			DbUtil.closeConn();
		}
		return articles;
	}
	
	public static List<Article> getStickSummary() {
		List<Article> articles = new ArrayList<Article>();
		try {
			Connection connection = DbUtil.getConn();
			Statement statement = connection.createStatement();
			String sql = "SELECT a.id,a.title,a.publish_time,a.category_id,a.content,a.category_code,a.type_id,a.type_code FROM d_article a where state=1 and hot=1 order by a.create_time desc  limit 1";
			ResultSet rs = statement.executeQuery(sql);
			while (rs.next()) {
				Article article = new Article();
				article.setId(rs.getLong("id"));
				article.setTitle(rs.getString("title"));
				article.setPublishTime(rs.getDate("publish_time"));
				article.setCategoryId(rs.getLong("category_id"));
				article.setCategoryCode(rs.getString("category_code"));
				article.setTypeId(rs.getLong("type_id"));
				String typeCode = rs.getString("type_code");
				article.setTypeCode(isEmpty(typeCode) ? article.getCategoryCode() : typeCode);
				String content = HtmlUtil.delHTMLTag(rs.getString("content")).trim();
				article.setContent(content.replaceAll("　", "").substring(0, Math.min(content.length(), 200)));
				articles.add(article);
			}
			rs.close();
			statement.close();
//			connection.close();
		} catch (Exception e) {
			System.out.println(name + "获取摘要数据发生异常：" + e.getMessage());
			e.printStackTrace();
			// 关闭连接
			DbUtil.closeConn();
		}
		return articles;
	}
	
	public static List<Article> getSticks() {
		List<Article> articles = new ArrayList<Article>();
		try {
			Connection connection = DbUtil.getConn();
			Statement statement = connection.createStatement();
			String sql = "SELECT a.id,a.title,a.publish_time,a.category_id,a.category_code,a.type_id,a.type_code FROM d_article a where state=1 and hot=1 order by a.create_time desc  limit 10";
			ResultSet rs = statement.executeQuery(sql);
			while (rs.next()) {
				Article article = new Article();
				article.setId(rs.getLong("id"));
				article.setTitle(rs.getString("title"));
				article.setPublishTime(rs.getDate("publish_time"));
				article.setCategoryId(rs.getLong("category_id"));
				article.setCategoryCode(rs.getString("category_code"));
				article.setTypeId(rs.getLong("type_id"));
				String typeCode = rs.getString("type_code");
				article.setTypeCode(isEmpty(typeCode) ? article.getCategoryCode() : typeCode);
				articles.add(article);
			}
			rs.close();
			statement.close();
//			connection.close();
		} catch (Exception e) {
			e.printStackTrace();
			// 关闭连接
			DbUtil.closeConn();
		}
		return articles;
	}
	
	/**
	 * 获取所有的图片地址
	 */
	public static List<Article> getSlides() {
		List<Article> slides = new ArrayList<Article>();
		try {
			Connection connection = DbUtil.getConn();
			Statement statement = connection.createStatement();
			String sql = "select id,category_code, type_code,title,content from d_article where state=1 order by publish_time desc limit 500";
			ResultSet rs = statement.executeQuery(sql);
			while(rs.next()) {
				Article slide = new Article();
				long id = rs.getLong("id");
				slide.setId(id);
				slide.setCategoryCode(rs.getString("category_code"));
				String typeCode = rs.getString("type_code");
				slide.setTypeCode(isEmpty(typeCode) ? slide.getCategoryCode() : typeCode);
				String content = rs.getString("content");
				// 提取src值
				List<String> imgSrcs = ImageUtil.getImgSrc(content);
				if(imgSrcs.isEmpty()) {
					continue;
				} else {
					String imgSrc = imgSrcs.get(0);
					if(!imgSrc.startsWith("http://image.kc890.com/")) continue;
					slide.setSourceUrl(imgSrc);
				}
				slide.setTitle(rs.getString("title"));
				slides.add(slide);
				if(slides.size() > 6) break;
			}
			rs.close();
			statement.close();
		} catch(Exception e) {
			System.out.println(name + "获取幻灯片数据发生异常：" + e.getMessage());
			e.printStackTrace();
			// 关闭连接
			DbUtil.closeConn();
		}
		return slides;
	}
	

	public static List<Article> getDetails(String publishTime) {
		List<Article> articles = new ArrayList<Article>();
		try {
			Connection connection = DbUtil.getConn();
			Statement statement = connection.createStatement();
			String sql = "select id,category_id, category_code, type_code,category_name, type_name,type_id,title,content,publish_time from d_article "
					+ "where create_time>'" + publishTime + "' and state=1";
			ResultSet rs = statement.executeQuery(sql);
			while (rs.next()) {
				Article article = new Article();
				article.setId(rs.getLong("id"));
				article.setTitle(rs.getString("title"));
				article.setContent(rs.getString("content"));
				article.setPublishTime(rs.getDate("publish_time"));
				article.setCategoryCode(rs.getString("category_code"));
				article.setTypeId(rs.getLong("type_id"));
				article.setCategoryId(rs.getLong("category_id"));
				String typeCode = rs.getString("type_code");
				article.setTypeCode(isEmpty(typeCode) ? article.getCategoryCode() : typeCode);
				String typeName = rs.getString("type_name");
				article.setTypeName(isEmpty(typeName) ? rs.getString("category_name") : typeName);
				
				articles.add(article);
			}
			rs.close();
			statement.close();
//			connection.close();
		} catch (Exception e) {
			e.printStackTrace();
			// 关闭连接
			DbUtil.closeConn();
		}
		return articles;
	}
	
	public static List<Article> getArticles(String t) {
		List<Article> articles = new ArrayList<Article>();
		try {
			Connection connection = DbUtil.getConn();
			Statement statement = connection.createStatement();
			// 查询最新10条记录
			String sql = "";
			if(t.equals("latest")) {
//				sql = "select * from d_article where state=1 order by create_time desc limit 10";
				sql = "select * from d_article order by rand() LIMIT 10";
			} else if(t.equals("hotest")) {
				sql = "select * from d_article where state=1 and hot=1 order by create_time desc limit 10";
			}
			ResultSet rs = statement.executeQuery(sql);
			while (rs.next()) {
				Article article = new Article();
				article.setId(rs.getLong("id"));
				article.setTitle(rs.getString("title"));
				article.setContent(rs.getString("content"));
				article.setPublishTime(rs.getDate("publish_time"));
				article.setCategoryCode(rs.getString("category_code"));
				String typeCode = rs.getString("type_code");
				article.setTypeCode(isEmpty(typeCode) ? article.getCategoryCode() : typeCode);
				String typeName = rs.getString("type_name");
				article.setTypeName(isEmpty(typeName) ? rs.getString("category_name") : typeName);
				
				articles.add(article);
			}
			rs.close();
			statement.close();
//			connection.close();
		} catch (Exception e) {
			e.printStackTrace();
			// 关闭连接
			DbUtil.closeConn();
		}
		return articles;
	}
	
	public static List<Category> getTypes() {
		List<Category> categories = new ArrayList<Category>();
		try {
			Connection connection = DbUtil.getConn();
			Statement statement = connection.createStatement();
			String sql = "select * from d_category";
			ResultSet rs = statement.executeQuery(sql);
			while(rs.next()) {
				Category category = new Category();
				long id = rs.getLong("id");
				category.setId(id);
				category.setCode(rs.getString("code"));
				category.setName(rs.getString("name"));
				category.setParentId(rs.getInt("parent_id"));
				categories.add(category);
			}
			rs.close();
			statement.close();
		} catch(Exception e) {
			e.printStackTrace();
			// 关闭连接
			DbUtil.closeConn();
		}
		return categories;
	}

	public static void main(String[] args) throws Exception {
		createHtml();
	}
	
	public static boolean isEmpty(String str) {
		return null == str || str.length() == 0;
	}

}
